<template>
  <div class="category-manage section-container">
    <div class="section-title">栏目管理</div>
    <div class="section-actions">
      <div class="actions-left">
        <el-button type="primary" @click="handleAdd">添加栏目</el-button>
      </div>
      <div class="actions-right">
        <el-button @click="handleBatchDelete">删除</el-button>
        <el-button @click="handleExpandAll">{{ isExpanded ? '收起全部' : '展开全部' }}</el-button>
        <el-button @click="handleShowLevel">{{ showLevel ? '隐藏层级' : '显示层级' }}</el-button>
      </div>
    </div>

    <!-- 表头 -->
    <div class="table-header">
      <span v-for="(item, index) in columns" :key="index" class="table-header-label" :style="{ width: item.width, flex: item.width ? 'none' : '1' }">
        {{ item.label }}
      </span>
    </div>

    <!-- 树形表格 -->
    <el-tree ref="treeRef" :data="treeData" :props="defaultProps" node-key="id" show-checkbox draggable :allow-drop="allowDrop" @node-drop="handleDrop" @node-expand="handleNodeExpand" @node-collapse="handleNodeCollapse" class="category-tree" v-loading="treeLoading">
      <template #default="{ node, data }">
        <div class="custom-tree-node">
          <!-- catId -->
          <span class="tree-cell catId-cell">
            {{ data.id }}
          </span>

          <!-- 名称列 固定宽度 -->
          <span class="tree-cell name-cell" :style="{ paddingLeft: (node.level - 1) * 20 + 'px' }">
            <template v-if="showLevel">{{ `${data.level} - ` }}</template>{{ data.name }}
          </span>

          <!-- 路径列 固定宽度 -->
          <span class="tree-cell uri-cell">
            {{ data.uri }}
          </span>

          <!-- 中间列 自适应 -->
          <div class="flex-cells">
            <!-- 类型列 -->
            <span class="tree-cell">
              {{ categoryTypeMapping[data.type] }}
            </span>

            <!-- 内容模型列 -->
            <span class="tree-cell">
              {{ data.modelId && data.modelId != -1 ? modelNameMapping[data.modelId] : '-' }}
            </span>

            <!-- 显示列 -->
            <span class="tree-cell" @click.stop>
              <el-switch
                v-model="data.isShow"
                :before-change="handleChangeShow.bind(this, data)"
                :loading="switchLoading && activeId === data.id && activeOption === 'isShow'"
                :active-value="true"
                :inactive-value="false"
              />
            </span>

            <!-- 启用列 -->
            <span class="tree-cell" @click.stop>
              <el-switch
                v-model="data.state"
                :before-change="handleChangeState.bind(this, data)"
                :loading="switchLoading && activeId === data.id && activeOption === 'state'"
                :active-value="0"
                :inactive-value="1"
              />
            </span>
          </div>

          <!-- 操作列 固定宽度 -->
          <span class="tree-cell operation-cell" @click.stop>
            <el-button v-permission="['build:category:list:preview']" type="primary" link size="small" @click="handlePreview(data)">预览</el-button>
            <el-button v-permission="['build:category:list:edit']" type="primary" link size="small" @click="handleEdit(data)">修改</el-button>
            <el-dropdown>
              <span class="el-dropdown-link">
                <i class="iconfont">&#xe771;</i>
              </span>
              <template #dropdown>
                <el-dropdown-menu>
                  <el-dropdown-item v-if="![1, 2, 3, 5, 10].includes(data.type)" @click="handleAddChild(data)">添加子栏目</el-dropdown-item>
                  <el-dropdown-item @click="handleCopy(data)">复制栏目</el-dropdown-item>
                  <el-dropdown-item @click="handleDelete(data)">删除</el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
          </span>
        </div>
      </template>
    </el-tree>
    <!-- 添加栏目 -->
    <el-drawer v-model="categoryDrawer" direction="rtl" :size="drawerSize">
      <template #header>
        <div class="drawer-header">
          <div class="drawer-header-title">{{ categoryId ? '编辑栏目' : '添加栏目' }}</div>
          <el-icon :size="18" @click="handleChangeSize"><FullScreen /></el-icon>
        </div>
      </template>
      <CategorySetting v-if="categoryDrawer" ref="categorySettingRef" />
      <template #footer>
        <el-button @click="categoryDrawer = false">取消</el-button>
        <el-button type="primary" @click="handleConfirm">确认</el-button>
      </template>
    </el-drawer>
    <!-- 复制栏目 -->
    <CategoryCopy @success="handleRestoreExpand" />
  </div>
</template>

<script setup>
import { ref, computed, provide, onMounted, nextTick } from 'vue'
import { useStore } from 'vuex'
import { ElMessage, ElMessageBox } from 'element-plus'
import { FullScreen } from '@element-plus/icons-vue'
import { deleteCategoryList, updateSort, deleteCategory, updateCategory } from '@/api/category'
import CategorySetting from './components/CategorySetting.vue'
import CategoryCopy from './components/CategoryCopy.vue'

const store = useStore()
store.dispatch('content/updateModelList')
store.dispatch('category/updateCategoryType')
const categoryId = computed(() => store.state.category.categoryId)
const currentSite = computed(() => store.state.site.currentSite)
const categoryDrawer = computed({
  get() {
    return store.state.category.categoryDrawer
  },
  set(val) {
    store.commit('category/SET_CATEGORY_DRAWER', val)
  }
})
// 栏目类型映射
const categoryTypeMapping = computed(() => {
  const typeList = store.state.category.categoryType
  const mapping = {}
  typeList.forEach(item => {
    mapping[item.dataValue] = item.dataKey
  })
  return mapping
})

// 内容模型映射
const modelNameMapping = computed(() => {
  const modelList = store.state.content.modelList
  const mapping = {}
  modelList.forEach(item => {
    mapping[item.id] = item.name
  })
  return mapping
})

// 栏目列表
const treeData = computed(() => store.state.category.siteCategoryTree)
const treeRef = ref(null)
const columns = [
  { label: 'catId', prop: 'id', width: '150px' },
  { label: '栏目名称', prop: 'name', width: '280px' },
  { label: '栏目路径', prop: 'uri', width: '200px' },
  { label: '栏目类型', prop: 'type', width: '' },
  { label: '内容模型', prop: 'modelId', width: '' },
  { label: '显示', prop: 'isShow', width: '' },
  { label: '启用', prop: 'state', width: '' },
  { label: '操作', prop: '', width: '150px' }
]
const defaultProps = {
  children: 'children',
  label: 'name'
}

// 拖拽排序
const allowDrop = (draggingNode, dropNode, type) => {
  // 只允许同级拖拽，type为'prev'或'next'时是同级
  if (type === 'inner') {
    return false
  }
  // 确保是同一父节点下的拖拽
  return draggingNode.parent === dropNode.parent
}

const handleDrop = async (draggingNode, dropNode, type) => {
  if (process.env.NODE_ENV === 'development') console.log(draggingNode, dropNode, type)
  // 获取当前层级所有节点
  const parent = dropNode.parent
  const children = parent.childNodes
  // 构建排序数据
  const sortData = children.map((node, index) => ({
    id: node.data.id,
    level: node.data.level,
    sortLevel: index + 1
  }))
  await updateSort({groupId: null, updateCategorySortVos: sortData})
}

// 添加栏目
const handleAdd = () => {
  store.commit('category/SET_CATEGORY_PID', null)
  store.commit('category/SET_CATEGORY_ID', null)
  store.commit('category/SET_CATEGORY_DRAWER', true)
}

// 提交栏目
const categorySettingRef = ref(null)
const handleConfirm = async () => {
  await categorySettingRef.value.submitCategoryForm()
  // 恢复展开状态
  nextTick(() => {
    handleRestoreExpand()
  })
}

// 批量删除栏目
const expandedKeys = ref(new Set())
const handleBatchDelete = () => {
  const checkedIds = Array.from(treeRef.value.getCheckedKeys())
  if (checkedIds.length === 0) {
    ElMessage.warning('请选择要删除的栏目')
    return
  }

  ElMessageBox.confirm(`此操作将永久删除选中的 ${checkedIds.length} 个栏目, 是否继续?`, '警告', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  })
    .then(async () => {
      try {
        deleteCategoryList(checkedIds).then(async res => {
          if (res.code === 20000) {
            ElMessage.success('批量删除成功')
            treeLoading.value = true
            await store.dispatch('category/updateCategory')
            // 恢复展开状态
            nextTick(() => {
              checkedIds.forEach(id => {
                expandedKeys.value.delete(id)
              })
              handleRestoreExpand()
            })
            treeLoading.value = false
          }
        })
      } catch (error) {
        ElMessage.error('删除失败')
      }
    })
    .catch(() => {
      ElMessage.info('已取消删除')
    })
}

// 编辑栏目
const handleEdit = data => {
  store.commit('category/SET_CATEGORY_PID', data.pid)
  store.commit('category/SET_CATEGORY_ID', data.id)
  store.commit('category/SET_CATEGORY_DRAWER', true)
}

// 预览栏目
const handlePreview = data => {
  let baseUrl = ''
  if (process.env.NODE_ENV == 'development') {
    baseUrl = 'http://10.10.0.20:9131'
  } else {
    baseUrl = store.state.base.groupSetting.baseUrl
  }
  const url = baseUrl + `/build${currentSite.value.uri}${data.uri}`
  window.open(url, '_blank')
}

// 添加子栏目
const handleAddChild = data => {
  store.commit('category/SET_CATEGORY_PID', data.id)
  store.commit('category/SET_CATEGORY_ID', null)
  store.commit('category/SET_CATEGORY_DRAWER', true)
}

// 复制栏目
const showCopyDialog = ref(false)
const sourceId = ref(null)
const sourceUri = ref(null)
provide('copyData', {
  showCopyDialog,
  sourceId,
  sourceUri
})
const handleCopy = data => {
  showCopyDialog.value = true
  sourceId.value = data.id
  sourceUri.value = data.uri
}

// 添加新的响应式变量
const treeLoading = ref(false)
const switchLoading = ref(false)
const activeId = ref(null)
const activeOption = ref(null)

// 修改 handleChangeShow 方法
const handleChangeShow = data => {
  switchLoading.value = true
  activeId.value = data.id
  activeOption.value = 'isShow'

  let _data = {
    id: data.id,
    isShow: !data.isShow
  }
  return new Promise((resolve, reject) => {
    updateCategory(_data)
      .then(res => {
        if (res.code === 20000) {
          ElMessage({
            showClose: true,
            message: '修改成功',
            type: 'success'
          })
          return resolve(true)
        }
      })
      .catch(() => {
        return reject(new Error('Error'))
      })
      .finally(() => {
        switchLoading.value = false
        activeId.value = null
        activeOption.value = null
      })
  })
}

// 修改 handleChangeState 方法
const handleChangeState = data => {
  switchLoading.value = true
  activeId.value = data.id
  activeOption.value = 'state'

  let _data = {
    id: data.id,
    state: data.state ? 0 : 1
  }
  return new Promise((resolve, reject) => {
    updateCategory(_data)
      .then(res => {
        if (res.code === 20000) {
          ElMessage({
            showClose: true,
            message: '修改成功',
            type: 'success'
          })
          return resolve(true)
        }
      })
      .catch(() => {
        return reject(new Error('Error'))
      })
      .finally(() => {
        switchLoading.value = false
        activeId.value = null
        activeOption.value = null
      })
  })
}

// 删除栏目
const handleDelete = data => {
  ElMessageBox.confirm('此操作将永久删除该栏目, 是否继续?', '警告', {
    confirmButtonText: '确定',
    cancelButtonText: '取消'
  })
    .then(() => {
      deleteCategory({ id: data.id }).then(async res => {
        if (res.code === 20000) {
          ElMessage.success('删除成功')
          treeLoading.value = true
          await store.dispatch('category/updateCategory')
          // 恢复展开状态
          nextTick(() => {
            handleRestoreExpand()
          })
          treeLoading.value = false
        }
      })
    })
    .catch(() => {
      ElMessage.info('已取消删除')
    })
}

// 在组件挂载时设置加载状态
onMounted(() => {
  treeLoading.value = true
  setTimeout(() => {
    treeLoading.value = false
  }, 500)
})

// 在 script setup 中添加新的响应式变量
const isExpanded = ref(false)
const showLevel = ref(false)

// 添加展开/收起全部的方法
const handleExpandAll = () => {
  isExpanded.value = !isExpanded.value
  if (isExpanded.value) {
    // 展开全部
    const traverse = (data) => {
      data.forEach(item => {
        treeRef.value.store.nodesMap[item.id]?.expand()
        if (item.children && item.children.length > 0) {
          traverse(item.children)
        }
      })
    }
    traverse(treeData.value)
  } else {
    // 收起全部
    treeRef.value.store.nodesMap && Object.values(treeRef.value.store.nodesMap).forEach(node => {
      node.collapse()
    })
  }
}

// 显示/隐藏层级
const handleShowLevel = () => {
  showLevel.value = !showLevel.value
}

// 展开节点
const handleNodeExpand = (data) => {
  expandedKeys.value.add(data.id)
}

// 折叠节点
const handleNodeCollapse = (data) => {
  expandedKeys.value.delete(data.id)
}

// 恢复展开
const handleRestoreExpand = () => {
  Array.from(expandedKeys.value).forEach(key => {
    treeRef.value.store.nodesMap[key]?.expand()
  })
}

// 改变抽屉大小
const drawerSize = ref(600)
const handleChangeSize = () => {
  drawerSize.value = drawerSize.value === 600 ? 1200 : 600
}
</script>

<style scoped lang="scss">
.table-header {
  display: flex;
  align-items: center;
  padding-left: 46px;
  height: 40px;
  background: #f8f8f8;
  border-bottom: 1px solid #e4e4e4;

  .table-header-label {
    box-sizing: border-box;
    font-size: 14px;
    color: #000000;
  }
}
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  font-size: 14px;
  width: 100%;
  box-sizing: border-box;

  .tree-cell {
    display: flex;
    align-items: center;
    box-sizing: border-box;
    white-space: pre-wrap;
    word-wrap: break-word;
    word-break: break-word;
  }

  .catId-cell {
    width: 150px;
    flex-shrink: 0;
  }

  .name-cell {
    width: 280px;
    flex-shrink: 0;
  }

  .uri-cell {
    width: 200px;
    flex-shrink: 0;
  }

  .flex-cells {
    display: flex;
    flex: 1;

    .tree-cell {
      flex: 1;
    }
  }

  .operation-cell {
    width: 150px;
    flex-shrink: 0;
    gap: 8px;
    i {
      color: $mainColor;
    }
  }
}

.category-tree {
  background: none;
  :deep(.el-tree-node) {
    white-space: nowrap;
    .el-tree-node__label {
      flex: 1;
    }
    .el-tree-node__content {
      height: 48px;
      border-bottom: 1px solid #e4e4e4;
      color: #000000;
      padding-left: 0 !important;
      .el-tree-node__expand-icon:not(.is-leaf) {
        color: #000000;
      }
    }
  }

  // 添加 loading 遮罩层样式
  :deep(.el-loading-mask) {
    background-color: rgba(255, 255, 255, 0.6);
  }
}

.drawer-header {
  display: flex;
  align-items: center;
  justify-content: space-between;

  .drawer-header-title {
    font-size: 18px;
    font-weight: bold;
    color: #333333;
  }

  .el-icon {
    cursor: pointer;
  }
}

</style>
